#ifndef __LIBNSTR__
#define __LIBNSTR__


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <stdarg.h>



#define NSTR_INITBUFFSIZE 1024
#define NSTR_SENDSIZE 2048
#define NSTR_FILEREADSIZE 8192
typedef struct
{
  // data string
  char  *data;
  // size of the data string
  int   size;
  // amount of data write in the the data string
  int   write;
} nstr_t;


typedef struct
{
  // path of the file
  char  *path; 
  FILE  *stream;
  long  size;
  long  read;
  char  *mime_type;
} nstrfile_t;


#define NSTR_INITTABLESIZE 64
typedef struct
{
  // data string
  nstr_t **table;
  // size of the data string
  int   size;
  // amount of elements in the the data string
  int   elements;
} nstrt_t;


// base functions
nstr_t  *nstr_make();
void    nstr_dispose(nstr_t *nstr);
nstr_t  *nstr_clean(nstr_t *nstr);

nstr_t  *nstr_sizeup(nstr_t *nstr);
nstr_t  *nstr_reserve(nstr_t *nstr, int size);

int     nstr_fill_with_file(nstr_t *nstr, const char *path);
int     nstr_read(nstr_t *nstr, int fd, int size);

nstr_t  *nstr_addnstr(nstr_t *nstr1, nstr_t *nstr2);
nstr_t  *nstr_addstr(nstr_t *nstr, const char *str);
nstr_t  *nstr_addstr_n(nstr_t *nstr, const char *str, int n);
nstr_t  *nstr_addchar(nstr_t *nstr, char c);
nstr_t  *nstr_addint(nstr_t *nstr, int i);
nstr_t  *nstr_addlong(nstr_t *nstr, long l);

nstr_t  *nstr_add(nstr_t *nstr, const char *str, ...);
nstr_t  *nstr_replace(nstr_t *nstr, const char *str, ...);

int     nstr_find_pos_after(nstr_t *nstr, const char *pattern
                            , int n, int start_from);
int     nstr_find_pos_begin(nstr_t *nstr, const char *pattern
                            , int n, int start_from);
nstr_t  *nstr_get_pattern(nstr_t *data, nstr_t *result
                          , const char *pattern , const char *end
                          , int n);
nstrt_t *nstr_split(nstrt_t *table, nstr_t *nstr, const char *pattern);

// error management
int     nstr_error(int error_id, int error_code);

// tables
nstrt_t *nstrt_make();
void    nstrt_dispose_all(nstrt_t *nstrt);
void    nstrt_dispose(nstrt_t *nstrt);
nstrt_t *nstrt_sizeup(nstrt_t *nstrt);

nstrt_t *nstrt_addend(nstrt_t *nstrt, nstr_t *element);
void    nstrt_addstrend(nstrt_t *nstrt, const char *str);
void    nstrt_removelast(nstrt_t *nstrt, nstr_t *element);
void    nstrt_deletelast(nstrt_t *nstrt);
nstr_t  *nstrt_getelem(nstrt_t *nstrt, int element);

// file acces
nstr_t  *nstr_file_read_all(nstr_t *nstr, const char *path);
nstrfile_t *nstr_open_file(const char *path);

// network access
int     nstr_send(nstr_t *nstr, int socket, int packet_size);


// low level
ssize_t __nstr_writen(int fd, const void *vptr, size_t n);



#endif


